`timescale 1ns / 1ps
module AHBsim(
    
);

reg clk;
reg rst_n;
reg[31:0] data;

initial begin
    data = 0;
    clk = 1; forever #2 clk = ~clk;
end

initial begin
    rst_n = 1; 
    #20 rst_n = 0;
    #20 rst_n = 1;
end
    

wire[31:0]  addr;
wire[2:0]   burst;
wire[1:0]   trans;
wire[31:0]  wdata;
wire        write;
wire[2:0]   size;
wire[31:0]  rdata;
wire        ready;
wire[1:0]   resp;
wire        grant;
wire        busreq;

reg[1:0]   so_respon;
reg[31:0]  so_rdata;
reg        so_rdata_valid;
reg        so_wait_req_n;
wire[31:0] si_address;
wire       si_write;
wire       si_read;
wire[11:0] su_burst_count;
wire       si_brust_begin;
wire       su_lock;
wire[31:0] si_wdata;

wire       mi_next;
reg [31:0] mo_wdata;
reg        mo_wdata_valid;
reg [31:0] mo_burst_addr;       
reg [2:0]  mo_data_size;
reg        mo_write;
reg        mo_read;
reg [31:0] mo_burst_data_num;
reg        mo_icont;
wire[31:0] mi_rdata;
wire[31:0] mi_raddr;
wire       mi_rdata_valid;

ahb_master u_ahb_master(
	.i_hclk     (clk                ),
    .i_hreset_n (rst_n              ),

    .o_haddr    (addr               ),
    .o_hburst   (burst              ),
    .o_htrans   (trans              ),
    .o_hwdata   (wdata              ),
    .o_hwrite   (write              ),
    .o_hsize    (size               ),
    .i_hrdata   (rdata              ),
    .i_hready   (ready              ),
    .i_hresp    (resp               ),
    .i_hgrant   (1'b1               ),
    .o_hbusreq  (busreq             ),

    .o_next     (mi_next             ),
    .i_data     (mo_wdata            ),
    .i_dav      (mo_wdata_valid      ),
    .i_addr     (mo_burst_addr       ),
    .i_size     (mo_data_size        ),
    .i_wr       (mo_write            ),
    .i_rd       (mo_read             ),
    .i_min_len  (mo_burst_data_num   ),
    .i_cont     (mo_icont            ),
    .o_data     (mi_rdata            ),
    .o_addr     (mi_raddr            ),
    .o_dav      (mi_rdata_valid      )
);

reg[31:0] reg0;
reg[31:0] reg1;
reg[31:0] reg2;
reg[31:0] reg3;
reg[31:0] reg4;
reg[31:0] reg5;

wire[31:0] i_reg0;
wire[31:0] i_reg1;
wire[31:0] i_reg2;
wire[31:0] i_reg3;
wire[31:0] i_reg4;
wire[31:0] i_reg5;

wire rorw;
wire ref;

assign i_reg0 = rorw ? reg0 : 32'hzzzz_zzzz;
assign i_reg1 = rorw ? reg1 : 32'hzzzz_zzzz;
assign i_reg2 = rorw ? reg2 : 32'hzzzz_zzzz;
assign i_reg3 = rorw ? reg3 : 32'hzzzz_zzzz;
assign i_reg4 = rorw ? reg4 : 32'hzzzz_zzzz;
assign i_reg5 = rorw ? reg5 : 32'hzzzz_zzzz;

AHBslave2Reg u_AHBslave2Reg(
	.clk     (clk     ),
    .rst_n   (rst_n   ),

    .HADDR   (addr   ),
    .HWRITE  (write  ),
    .HSIZE   (size   ),
    .HBURST  (burst  ),
    .HTRANS  (trans  ),
    .HWDATA  (wdata  ),
    .HREADY  (ready  ),
    .HRESP   (resp   ),
    .HRDATA  (rdata  ),

    .io_reg0 (i_reg0 ),
    .io_reg1 (i_reg1 ),
    .io_reg2 (i_reg2 ),
    .io_reg3 (i_reg3 ),
    .io_reg4 (i_reg4 ),
    .io_reg5 (i_reg5 ),
    .r_or_w  (rorw    ),
    .refresh (ref     )
);


always @(posedge ref) begin
    reg0 <= i_reg0;
    reg1 <= i_reg1;
    reg2 <= i_reg2;
    reg3 <= i_reg3;
    reg4 <= i_reg4;
    reg5 <= i_reg5;
end

always @(negedge ref) begin
    reg0 <= i_reg0;
    reg1 <= i_reg1;
    reg2 <= i_reg2;
    reg3 <= i_reg3;
    reg4 <= i_reg4;
    reg5 <= i_reg5;
end

reg s1;
reg s2;
wire clk1;
wire clk2;

assign clk1 = clk & s1;
assign clk2 = clk & s2;

always @(posedge clk or negedge rst_n) begin
    if (rst_n) begin
       
    end else begin
        so_rdata <= 8'h00;
        so_rdata_valid <= 1'b1;
        so_wait_req_n <= 1;
        mo_burst_data_num <= 8'hf0;
        mo_wdata <= 8'h00;
        mo_wdata_valid <= 1'b1;
        mo_data_size <= 3'b010;
        mo_icont <= 0;
        so_respon <= 1'b0;
    end
end

reg[7:0] counter0;
always @(posedge clk or negedge rst_n) begin
    if (rst_n) begin
        mo_read <= 0;
        mo_write <= 1;
        if (counter0 < 5) begin
            mo_wdata <= mo_wdata + 4;
            mo_burst_addr <= mo_burst_addr + 1;
            counter0 <= counter0 + 1;
        end else begin
            s1 <= 1;
        end
    end else begin
        counter0 <= 0;
        mo_burst_addr <= 32'h2000_0000;
        s1 <= 0;
    end
end

reg[7:0] counter1;
always @(posedge clk1 or negedge rst_n) begin
    if (rst_n) begin
        if (counter1 < 10) begin
            counter1 <= counter1 + 1;
        end else begin
            s1 <= 0;
            s2 <= 1;
        end
    end else begin
        counter1 <= 0;
        s2 <= 0;
    end
end



reg[7:0] counter2;
reg[31:0] m1;

reg[31:0] read_addr;
reg[31:0] read_data;
always @(posedge clk2) begin
    if (mi_rdata_valid === 1) begin
        read_addr <= mi_raddr;
        read_data <= mi_rdata;
    end else begin
        
    end
end

always @(posedge clk2 or negedge rst_n) begin
    if (rst_n) begin
        if (counter2 < 6) begin
            mo_read <= 1;
            mo_write <= 0;
            mo_burst_addr <= m1;
            if (mi_next === 1) begin
                mo_burst_addr <= m1 + 1;
                m1 <= m1 + 1;
                counter2 <= counter2 + 1; 
            end else begin
                
            end
        end else begin
            s2 <= 1;
        end
    end else begin
        counter2 <= 0;
        m1 <= 32'h2000_0000;
    end
end
endmodule // AHBsim